import { marked } from 'marked'
import hljs from 'highlight.js'

// 配置 highlight.js
hljs.configure({
  languages: ['javascript', 'typescript', 'html', 'css', 'json', 'bash', 'python', 'java', 'cpp', 'c', 'sql']
})

/**
 * 高亮代码
 * @param code 代码文本
 * @param language 编程语言
 * @returns rich-text 节点数组
 */
function highlightCode(code: string, language: string): any[] {
  try {
    let highlighted: string
    
    if (language && hljs.getLanguage(language)) {
      highlighted = hljs.highlight(code, { language }).value
    } else {
      highlighted = hljs.highlightAuto(code).value
    }
    
    // 将高亮的 HTML 转换为 rich-text 节点
    return parseHighlightedHtml(highlighted)
  } catch (error) {
    console.error('代码高亮错误:', error)
    return [{ type: 'text', text: code }]
  }
}

/**
 * 解析高亮的 HTML 为 rich-text 节点
 * @param html 高亮的 HTML
 * @returns rich-text 节点数组
 */
function parseHighlightedHtml(html: string): any[] {
  const nodes: any[] = []
  
  // 简单的 HTML 解析，处理 span 标签
  const spanRegex = /<span[^>]*class="([^"]*)"[^>]*>([^<]*)<\/span>/g
  let lastIndex = 0
  let match
  
  while ((match = spanRegex.exec(html)) !== null) {
    // 添加 span 前的文本
    if (match.index > lastIndex) {
      const beforeText = html.slice(lastIndex, match.index)
      if (beforeText) {
        nodes.push({ type: 'text', text: beforeText })
      }
    }
    
    // 添加高亮的 span
    const className = match[1]
    const text = match[2]
    const color = getHighlightColor(className)
    
    nodes.push({
      type: 'node',
      name: 'span',
      attrs: {
        style: `color: ${color};`
      },
      children: [{ type: 'text', text }]
    })
    
    lastIndex = match.index + match[0].length
  }
  
  // 添加剩余文本
  if (lastIndex < html.length) {
    const remainingText = html.slice(lastIndex).replace(/<[^>]*>/g, '')
    if (remainingText) {
      nodes.push({ type: 'text', text: remainingText })
    }
  }
  
  return nodes.length > 0 ? nodes : [{ type: 'text', text: html.replace(/<[^>]*>/g, '') }]
}

/**
 * 根据 highlight.js 类名获取颜色
 * @param className 类名
 * @returns 颜色值
 */
function getHighlightColor(className: string): string {
  const colorMap: { [key: string]: string } = {
    'hljs-keyword': '#d73a49',      // 关键字 - 红色
    'hljs-string': '#032f62',       // 字符串 - 深蓝色
    'hljs-comment': '#6a737d',      // 注释 - 灰色
    'hljs-number': '#005cc5',       // 数字 - 蓝色
    'hljs-function': '#6f42c1',     // 函数 - 紫色
    'hljs-variable': '#e36209',     // 变量 - 橙色
    'hljs-type': '#005cc5',         // 类型 - 蓝色
    'hljs-built_in': '#005cc5',     // 内置函数 - 蓝色
    'hljs-literal': '#005cc5',      // 字面量 - 蓝色
    'hljs-attr': '#005cc5',         // 属性 - 蓝色
    'hljs-tag': '#22863a',          // 标签 - 绿色
    'hljs-name': '#22863a',         // 名称 - 绿色
    'hljs-attribute': '#6f42c1',    // 属性名 - 紫色
    'hljs-value': '#032f62',        // 属性值 - 深蓝色
  }
  
  // 查找匹配的类名
  for (const [key, color] of Object.entries(colorMap)) {
    if (className.includes(key)) {
      return color
    }
  }
  
  return '#24292e' // 默认颜色
}

// 配置 marked
marked.setOptions({
  breaks: true, // 支持换行
  gfm: true, // 支持 GitHub Flavored Markdown
})

/**
 * 将 Markdown 文本转换为 HTML
 * @param markdownText Markdown 文本
 * @returns HTML 字符串
 */
export function markdownToHtml(markdownText: string): string {
  if (!markdownText) return ''
  
  try {
    const result = marked(markdownText)
    return typeof result === 'string' ? result : String(result)
  } catch (error) {
    console.error('Markdown 解析错误:', error)
    return markdownText // 如果解析失败，返回原文本
  }
}

/**
 * 将 Markdown 文本转换为 uni-app rich-text 支持的节点格式
 * @param markdownText Markdown 文本
 * @returns rich-text 节点数组
 */
export function markdownToRichText(markdownText: string): any[] {
  if (!markdownText) return []
  
  try {
    // 直接解析 Markdown 文本为 rich-text 节点
    return parseMarkdownToRichText(markdownText)
  } catch (error) {
    console.error('Markdown 转换错误:', error)
    return [{ type: 'text', text: markdownText }]
  }
}

/**
 * 直接解析 Markdown 文本为 rich-text 节点
 * @param markdownText Markdown 文本
 * @returns rich-text 节点数组
 */
function parseMarkdownToRichText(markdownText: string): any[] {
  const nodes: any[] = []
  const lines = markdownText.split('\n')
  
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i]
    
    // 处理标题
    if (line.startsWith('#')) {
      const level = line.match(/^#+/)?.[0].length || 1
      const text = line.replace(/^#+\s*/, '').trim()
      nodes.push({
        type: 'node',
        name: `h${Math.min(level, 6)}`,
        attrs: {
          style: `font-size: ${24 - level * 2}px; font-weight: bold; margin: 16px 0 8px 0;`
        },
        children: [{ type: 'text', text }]
      })
    }
    // 处理代码块
    else if (line.startsWith('```')) {
      const language = line.replace(/```/, '').trim()
      const codeLines = []
      i++ // 跳过开始标记
      
      while (i < lines.length && !lines[i].startsWith('```')) {
        codeLines.push(lines[i])
        i++
      }
      
      const codeText = codeLines.join('\n')
      const highlightedCode = highlightCode(codeText, language)
      
      nodes.push({
        type: 'node',
        name: 'pre',
        attrs: {
          style: 'background-color: #f6f8fa; padding: 16px; border-radius: 8px; overflow-x: auto; margin: 16px 0; border: 1px solid #e1e4e8;'
        },
        children: [{
          type: 'node',
          name: 'code',
          attrs: {
            style: 'font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace; font-size: 14px; line-height: 1.5;'
          },
          children: highlightedCode
        }]
      })
    }
    // 处理引用
    else if (line.startsWith('>')) {
      const text = line.replace(/^>\s*/, '').trim()
      nodes.push({
        type: 'node',
        name: 'blockquote',
        attrs: {
          style: 'border-left: 4px solid #dfe2e5; padding-left: 16px; margin: 16px 0; color: #6a737d;'
        },
        children: [{ type: 'text', text }]
      })
    }
    // 处理列表 - 去掉缩进和标记，直接作为段落处理
    else if (line.match(/^\s*[-*+]\s/) || line.match(/^\s*\d+\.\s/)) {
      const text = line.replace(/^\s*[-*+\d.]\s/, '').trim()
      nodes.push({
        type: 'node',
        name: 'p',
        attrs: {
          style: 'margin: 8px 0; line-height: 1.6;'
        },
        children: parseInlineMarkdown(text)
      })
    }
    // 处理普通段落
    else if (line.trim()) {
      const text = line.trim()
      nodes.push({
        type: 'node',
        name: 'p',
        attrs: {
          style: 'margin: 16px 0; line-height: 1.6;'
        },
        children: parseInlineMarkdown(text)
      })
    }
    // 处理空行
    else {
      nodes.push({ type: 'text', text: '\n' })
    }
  }
  
  return nodes
}

/**
 * 解析行内 Markdown 格式
 * @param text 文本
 * @returns rich-text 节点数组
 */
function parseInlineMarkdown(text: string): any[] {
  const nodes: any[] = []
  
  // 处理行内代码 `code`
  const codeRegex = /`([^`]+)`/g
  let lastIndex = 0
  let match
  
  while ((match = codeRegex.exec(text)) !== null) {
    // 添加代码前的文本
    if (match.index > lastIndex) {
      const beforeText = text.slice(lastIndex, match.index)
      if (beforeText) {
        nodes.push(...parseBoldText(beforeText))
      }
    }
    
    // 添加行内代码
    nodes.push({
      type: 'node',
      name: 'code',
      attrs: {
        style: 'background-color: #f1f3f4; color: #1976d2; padding: 2px 4px; border-radius: 3px; font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace; font-size: 0.9em;'
      },
      children: [{ type: 'text', text: match[1] }]
    })
    
    lastIndex = match.index + match[0].length
  }
  
  // 添加剩余文本
  if (lastIndex < text.length) {
    const remainingText = text.slice(lastIndex)
    if (remainingText) {
      nodes.push(...parseBoldText(remainingText))
    }
  }
  
  return nodes.length > 0 ? nodes : [{ type: 'text', text }]
}

/**
 * 解析粗体文本
 * @param text 文本
 * @returns rich-text 节点数组
 */
function parseBoldText(text: string): any[] {
  const nodes: any[] = []
  
  // 处理粗体 **text**
  const boldRegex = /\*\*(.*?)\*\*/g
  let lastIndex = 0
  let match
  
  while ((match = boldRegex.exec(text)) !== null) {
    // 添加粗体前的文本
    if (match.index > lastIndex) {
      const beforeText = text.slice(lastIndex, match.index)
      if (beforeText) {
        nodes.push({ type: 'text', text: beforeText })
      }
    }
    
    // 添加粗体文本
    nodes.push({
      type: 'node',
      name: 'strong',
      attrs: {
        style: 'font-weight: bold;'
      },
      children: [{ type: 'text', text: match[1] }]
    })
    
    lastIndex = match.index + match[0].length
  }
  
  // 添加剩余文本
  if (lastIndex < text.length) {
    const remainingText = text.slice(lastIndex)
    if (remainingText) {
      nodes.push({ type: 'text', text: remainingText })
    }
  }
  
  return nodes.length > 0 ? nodes : [{ type: 'text', text }]
}

/**
 * 将 HTML 字符串解析为 rich-text 节点格式
 * @param html HTML 字符串
 * @returns rich-text 节点数组
 */
function parseHtmlToRichText(html: string): any[] {
  const nodes: any[] = []
  
  // 处理代码块
  const codeBlockRegex = /<pre><code[^>]*class="[^"]*hljs[^"]*"[^>]*>([\s\S]*?)<\/code><\/pre>/g
  let lastIndex = 0
  let match
  
  while ((match = codeBlockRegex.exec(html)) !== null) {
    // 添加代码块前的文本
    if (match.index > lastIndex) {
      const textContent = html.slice(lastIndex, match.index)
      if (textContent.trim()) {
        nodes.push(...parseTextToNodes(textContent))
      }
    }
    
    // 添加代码块
    nodes.push({
      type: 'node',
      name: 'pre',
      attrs: {
        style: 'background-color: #f6f8fa; padding: 16px; border-radius: 8px; overflow-x: auto; margin: 16px 0; border: 1px solid #e1e4e8;'
      },
      children: [{
        type: 'node',
        name: 'code',
        attrs: {
          style: 'font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace; font-size: 14px; line-height: 1.5;'
        },
        children: [{
          type: 'text',
          text: match[1].replace(/<[^>]*>/g, '') // 移除内部 HTML 标签
        }]
      }]
    })
    
    lastIndex = match.index + match[0].length
  }
  
  // 添加剩余文本
  if (lastIndex < html.length) {
    const textContent = html.slice(lastIndex)
    if (textContent.trim()) {
      nodes.push(...parseTextToNodes(textContent))
    }
  }
  
  // 如果没有匹配到代码块，直接解析整个 HTML
  if (nodes.length === 0) {
    return parseTextToNodes(html)
  }
  
  return nodes
}

/**
 * 将文本内容解析为 rich-text 节点
 * @param text 文本内容
 * @returns rich-text 节点数组
 */
function parseTextToNodes(text: string): any[] {
  const nodes: any[] = []
  
  // 处理换行
  const lines = text.split('\n')
  lines.forEach((line, index) => {
    if (line.trim()) {
      // 处理粗体 **text**
      const boldRegex = /\*\*(.*?)\*\*/g
      let lastIndex = 0
      let match
      
      while ((match = boldRegex.exec(line)) !== null) {
        // 添加粗体前的文本
        if (match.index > lastIndex) {
          const beforeText = line.slice(lastIndex, match.index)
          if (beforeText) {
            nodes.push({ type: 'text', text: beforeText })
          }
        }
        
        // 添加粗体文本
        nodes.push({
          type: 'node',
          name: 'strong',
          children: [{ type: 'text', text: match[1] }]
        })
        
        lastIndex = match.index + match[0].length
      }
      
      // 添加剩余文本
      if (lastIndex < line.length) {
        const remainingText = line.slice(lastIndex)
        if (remainingText) {
          nodes.push({ type: 'text', text: remainingText })
        }
      }
    }
    
    // 添加换行（除了最后一行）
    if (index < lines.length - 1) {
      nodes.push({ type: 'text', text: '\n' })
    }
  })
  
  return nodes
}